[BLK] back: Allocate pages for foreign mappings individually rather
authorkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 5 Oct 2006 21:11:24 +0000 (22:11 +0100)
committerkaf24@firebug.cl.cam.ac.uk <kaf24@firebug.cl.cam.ac.uk>
Thu, 5 Oct 2006 21:11:24 +0000 (22:11 +0100)
than in one large contiguous region.
Signed-off-by: Keir Fraser <keir@xensource.com>
linux-2.6-xen-sparse/drivers/xen/balloon/balloon.c
linux-2.6-xen-sparse/drivers/xen/blkback/blkback.c
linux-2.6-xen-sparse/include/xen/balloon.h

index a6a8396c05a2719ea58983cebc118d9f46a57a82..ad3965566150ff1a6e53e2512621b9e231346b74 100644 (file)
@@ -606,6 +606,17 @@ void balloon_dealloc_empty_page_range(
        schedule_work(&balloon_worker);
 }
 
+struct page *balloon_alloc_empty_page(void)
+{
+       return balloon_alloc_empty_page_range(1);
+}
+
+void balloon_free_empty_page(
+       struct page *page)
+{
+       balloon_dealloc_empty_page_range(page, 1);
+}
+
 void balloon_release_driver_page(struct page *page)
 {
        unsigned long flags;
@@ -621,6 +632,8 @@ void balloon_release_driver_page(struct page *page)
 EXPORT_SYMBOL_GPL(balloon_update_driver_allowance);
 EXPORT_SYMBOL_GPL(balloon_alloc_empty_page_range);
 EXPORT_SYMBOL_GPL(balloon_dealloc_empty_page_range);
+EXPORT_SYMBOL_GPL(balloon_alloc_empty_page);
+EXPORT_SYMBOL_GPL(balloon_free_empty_page);
 EXPORT_SYMBOL_GPL(balloon_release_driver_page);
 
 MODULE_LICENSE("Dual BSD/GPL");
index 416f7bc18c8b271c73a338402dc20f2f56814bcc..5d5856d8f90a844932df6b0eee4c44e0ed16c5d3 100644 (file)
@@ -56,8 +56,6 @@ static int blkif_reqs = 64;
 module_param_named(reqs, blkif_reqs, int, 0);
 MODULE_PARM_DESC(reqs, "Number of blkback requests to allocate");
 
-static int mmap_pages;
-
 /* Run-time switchable: /sys/module/blkback/parameters/ */
 static unsigned int log_stats = 0;
 static unsigned int debug_lvl = 0;
@@ -87,8 +85,7 @@ static DECLARE_WAIT_QUEUE_HEAD(pending_free_wq);
 
 #define BLKBACK_INVALID_HANDLE (~0)
 
-static unsigned long mmap_vstart;
-static unsigned long *pending_vaddrs;
+static struct page **pending_pages;
 static grant_handle_t *pending_grant_handles;
 
 static inline int vaddr_pagenr(pending_req_t *req, int seg)
@@ -98,7 +95,8 @@ static inline int vaddr_pagenr(pending_req_t *req, int seg)
 
 static inline unsigned long vaddr(pending_req_t *req, int seg)
 {
-       return pending_vaddrs[vaddr_pagenr(req, seg)];
+       unsigned long pfn = page_to_pfn(pending_pages[vaddr_pagenr(req, seg)]);
+       return (unsigned long)pfn_to_kaddr(pfn);
 }
 
 #define pending_handle(_req, _seg) \
@@ -506,52 +504,50 @@ static void make_response(blkif_t *blkif, unsigned long id,
 
 static int __init blkif_init(void)
 {
-       struct page *page;
-       int i;
+       int i, mmap_pages;
 
        if (!is_running_on_xen())
                return -ENODEV;
 
-       mmap_pages            = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
-
-       page = balloon_alloc_empty_page_range(mmap_pages);
-       if (page == NULL)
-               return -ENOMEM;
-       mmap_vstart = (unsigned long)pfn_to_kaddr(page_to_pfn(page));
+       mmap_pages = blkif_reqs * BLKIF_MAX_SEGMENTS_PER_REQUEST;
 
        pending_reqs          = kmalloc(sizeof(pending_reqs[0]) *
                                        blkif_reqs, GFP_KERNEL);
        pending_grant_handles = kmalloc(sizeof(pending_grant_handles[0]) *
                                        mmap_pages, GFP_KERNEL);
-       pending_vaddrs        = kmalloc(sizeof(pending_vaddrs[0]) *
+       pending_pages         = kmalloc(sizeof(pending_pages[0]) *
                                        mmap_pages, GFP_KERNEL);
-       if (!pending_reqs || !pending_grant_handles || !pending_vaddrs) {
-               kfree(pending_reqs);
-               kfree(pending_grant_handles);
-               kfree(pending_vaddrs);
-               printk("%s: out of memory\n", __FUNCTION__);
-               return -ENOMEM;
-       }
+       if (!pending_reqs || !pending_grant_handles || !pending_pages)
+               goto out_of_memory;
 
-       blkif_interface_init();
-       
-       printk("%s: reqs=%d, pages=%d, mmap_vstart=0x%lx\n",
-              __FUNCTION__, blkif_reqs, mmap_pages, mmap_vstart);
-       BUG_ON(mmap_vstart == 0);
        for (i = 0; i < mmap_pages; i++) {
-               pending_vaddrs[i] = mmap_vstart + (i << PAGE_SHIFT);
+               pending_pages[i] = balloon_alloc_empty_page();
+               if (pending_pages[i] == NULL) {
+                       while (--i >= 0)
+                               balloon_free_empty_page(pending_pages[i]);
+                       goto out_of_memory;
+               }
                pending_grant_handles[i] = BLKBACK_INVALID_HANDLE;
        }
 
+       blkif_interface_init();
+
        memset(pending_reqs, 0, sizeof(pending_reqs));
        INIT_LIST_HEAD(&pending_free);
 
        for (i = 0; i < blkif_reqs; i++)
                list_add_tail(&pending_reqs[i].free_list, &pending_free);
-    
+
        blkif_xenbus_init();
 
        return 0;
+
+ out_of_memory:
+       kfree(pending_reqs);
+       kfree(pending_grant_handles);
+       kfree(pending_pages);
+       printk("%s: out of memory\n", __FUNCTION__);
+       return -ENOMEM;
 }
 
 module_init(blkif_init);
index 60d7099aa10d8231080bfd93d8bf5e012b4786dd..4e27a2e39a76a826fc687a1bfacb0e03d3d94c72 100644 (file)
  * Inform the balloon driver that it should allow some slop for device-driver
  * memory activities.
  */
-void
-balloon_update_driver_allowance(
-       long delta);
+void balloon_update_driver_allowance(long delta);
 
 /* Allocate an empty low-memory page range. */
-struct page *
-balloon_alloc_empty_page_range(
-       unsigned long nr_pages);
+struct page *balloon_alloc_empty_page_range(unsigned long nr_pages);
 
 /* Deallocate an empty page range, adding to the balloon. */
-void
-balloon_dealloc_empty_page_range(
+void balloon_dealloc_empty_page_range(
        struct page *page, unsigned long nr_pages);
 
-void
-balloon_release_driver_page(
-       struct page *page);
+struct page *balloon_alloc_empty_page(void);
+void balloon_free_empty_page(struct page *page);
+
+void balloon_release_driver_page(struct page *page);
 
 /*
  * Prevent the balloon driver from changing the memory reservation during